﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Kugar.Core.Collections;

namespace Kugar.Core.WinForm.ControlExtMethod
{
    /// <summary>
    ///     用于处理DataGridView的双层表头
    /// </summary>
    public class DataGridViewMutilColumnHeaderManager
    {
        private DataGridView _targetGrid = null;

        public DataGridViewMutilColumnHeaderManager(DataGridView targetGrid)
        {
            Columns = new ListEx<MutilColumnHeaderItemBase>();

            Columns.CollectionChanged += Columns_CollectionChanged;

            _targetGrid = targetGrid;

            _targetGrid.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
            _targetGrid.ColumnHeadersHeight = _targetGrid.ColumnHeadersHeight * 2;
            _targetGrid.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomCenter;

            _targetGrid.ColumnWidthChanged += dataGridView_ColumnWidthChanged;
            _targetGrid.Scroll += dataGridView_Scroll;
            _targetGrid.Paint += dataGridView_Paint;
            _targetGrid.CellPainting += dataGridView_CellPainting;

            _targetGrid.Refresh();
        }

        void Columns_CollectionChanged(object sender, NotifyCollectionChangedEventArgs<MutilColumnHeaderItemBase> e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                for (int i = 0; i < e.NewItems.Count; i++)
                {
                    e.NewItems[i].TargetDataGridView = _targetGrid;
                }

                _targetGrid.Refresh();
            }
        }

        public ListEx<MutilColumnHeaderItemBase> Columns { get; private set; }

        private void dataGridView_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
        {
            var rtHeader = this._targetGrid.DisplayRectangle;
            rtHeader.Height = this._targetGrid.ColumnHeadersHeight / 2;
            this._targetGrid.Invalidate(rtHeader);
        }

        private void dataGridView_Scroll(object sender, ScrollEventArgs e)
        {
            var rtHeader = _targetGrid.DisplayRectangle;

            rtHeader.Height = _targetGrid.ColumnHeadersHeight / 2;
            _targetGrid.Invalidate(rtHeader);
        }

        private void dataGridView_Paint(object sender, PaintEventArgs e)
        {
            if (Columns.Count <= 0)
            {
                return;
            }

            var cellStyle = _targetGrid.ColumnHeadersDefaultCellStyle;

            for (int i = 0; i < Columns.Count; i++)
            {
                var item = Columns[i];

                var r1 = new Rectangle();// _targetGrid.GetCellDisplayRectangle(i, -1, true);

                var firstCell = _targetGrid.GetCellDisplayRectangle(item.StartColumnIndex, -1, true);

                r1.X += firstCell.X;
                r1.Y += firstCell.Y;
                r1.Height = firstCell.Height / 2 - 1;

                for (int j = item.StartColumnIndex; j <= item.EndColumnIndex; j++)
                {
                    var tempCell = _targetGrid.GetCellDisplayRectangle(j, -1, true);

                    r1.Width = r1.Width + tempCell.Width;
                }

                r1.Width -= 1;


                e.Graphics.FillRectangle(new SolidBrush(cellStyle.BackColor), r1);

                //e.Graphics.DrawLine(new Pen(Color.Black), r1.X, r1.Height, r1.Width, r1.Height);

                if (string.IsNullOrWhiteSpace(item.HeaderText))
                {
                    continue;
                }

                var format = new StringFormat();

                format.Alignment = StringAlignment.Center;
                format.LineAlignment = StringAlignment.Center;
                e.Graphics.DrawString(item.HeaderText, cellStyle.Font, new SolidBrush(cellStyle.ForeColor), r1, format);
            }
        }

        private void dataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex == 1 && e.ColumnIndex > -1)
            {
                var r2 = e.CellBounds;
                r2.Y += e.CellBounds.Height / 2;
                r2.Height = e.CellBounds.Height / 2;
                e.PaintBackground(r2, true);
                e.PaintContent(r2);
                e.Handled = true;
            }
        }
    }

    /// <summary>
    ///     双层表头分组信息的基类
    /// </summary>
    public abstract class MutilColumnHeaderItemBase : INotifyPropertyChanged
    {
        internal MutilColumnHeaderItemBase()
        {
            //_startColumnIndex = 0;
            //_endColumnIndex = 0;
        }

        //public MutiColumnHeaderItemBase(int startColumnIndex, int endColumnIndex)
        //{
        //    _startColumnIndex = startColumnIndex;
        //    _endColumnIndex = endColumnIndex;
        //}

        /// <summary>
        ///     起始列的Index
        /// </summary>
        public abstract int StartColumnIndex { get; }

        /// <summary>
        ///     结束列的Index
        /// </summary>
        public abstract int EndColumnIndex { get; }

        /// <summary>
        ///     合并后的表头文本
        /// </summary>
        public string HeaderText { set; get; }

        /// <summary>
        ///     关联的是哪个DataGridView
        /// </summary>
        public DataGridView TargetDataGridView { internal set; get; }

        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

    }

    /// <summary>
    ///     按列索引号作为配置的双层表头
    /// </summary>
    public class MutilColumnHeaderItemByIndex : MutilColumnHeaderItemBase
    {
        private int _startColumnIndex;
        private int _endColumnIndex;

        internal MutilColumnHeaderItemByIndex()
        {
            _startColumnIndex = 0;
            _endColumnIndex = 0;
        }

        public MutilColumnHeaderItemByIndex(int startColumnIndex, int endColumnIndex, string headerText)
        {
            this.SetValue(startColumnIndex, endColumnIndex);
            HeaderText = headerText;
            //_startColumnIndex = startColumnIndex;
            //_endColumnIndex = endColumnIndex;
        }

        public override int StartColumnIndex
        {
            get { return _startColumnIndex; }
        }

        public override int EndColumnIndex
        {
            get { return _endColumnIndex; }
        }

        public void SetValue(int startIndex, int endIndex)
        {
            if (startIndex < 0)
            {
                throw new ArgumentOutOfRangeException("startIndex", "必须大于0");
            }

            if (endIndex < 0)
            {
                throw new ArgumentOutOfRangeException("endIndex", "必须大于0");
            }

            if (startIndex > endIndex)
            {
                throw new ArgumentOutOfRangeException("startIndex", "起始列序号不能大于结束序号");
            }

            if (_startColumnIndex != startIndex)
            {
                _startColumnIndex = startIndex;
                OnPropertyChanged("StartColumnIndex");
            }

            if (_endColumnIndex != endIndex)
            {
                _endColumnIndex = endIndex;
                OnPropertyChanged("EndColumnIndex");
            }
        }

    }

    public class MutilColumnHeaderItemByName : MutilColumnHeaderItemBase
    {
        private string _startColumnName;
        private string _endColumnName;

        public MutilColumnHeaderItemByName(string startColumnName, string endColumnName, string headerText)
        {
            this.SetValue(startColumnName, endColumnName);

            HeaderText = headerText;
            //_startColumnIndex = startColumnIndex;
            //_endColumnIndex = endColumnIndex;
        }

        public override int StartColumnIndex
        {
            get
            {
                if (TargetDataGridView == null)
                {
                    return 0;
                }
                else
                {
                    return TargetDataGridView.Columns[_startColumnName].DisplayIndex;
                }
            }
        }

        public override int EndColumnIndex
        {
            get
            {
                if (TargetDataGridView == null)
                {
                    return 0;
                }
                else
                {
                    return TargetDataGridView.Columns[_endColumnName].DisplayIndex;
                }
            }
        }

        public void SetValue(string startColumnName, string endColumnName)
        {
            if (string.IsNullOrWhiteSpace(startColumnName))
            {
                throw new ArgumentOutOfRangeException("startColumnName");
            }

            if (string.IsNullOrWhiteSpace(endColumnName))
            {
                throw new ArgumentOutOfRangeException("endColumnName");
            }

            if (_startColumnName != startColumnName)
            {
                _startColumnName = startColumnName;
                OnPropertyChanged("StartColumnIndex");
            }

            if (_endColumnName != endColumnName)
            {
                _endColumnName = endColumnName;
                OnPropertyChanged("EndColumnIndex");
            }
        }

    }
}
